/**
 * @class   wosh::SystemMonitor
 * @brief   CoreModule designed for diagnostic purposes, collects wosh::SystemError
 *          system information and provides access to profiling data (when enabled).
 *
 *
 * \image html diagrams/SystemMonitor.png "wosh::SystemMonitor UML diagram"
 *
 * @ingroup CoreModules
 ****************************************************************************
 * @version 0.8.161 $Id: SystemMonitor.h 2827 2010-08-02 11:01:48Z alex $
 * @author  Alessandro Polo
 ****************************************************************************/
/*! \page page_core
 * \htmlonly <hr/> \endhtmlonly
 * \section page_core_systemmonitor Monitoring
 *
 * wosh::SystemMonitor is a diagnostic core module designed to log wosh::SystemError
 * (raised by generic components), gather local system-information (PID, memory, ..),
 * forward access to wosh::SystemProfiler data (when \c profiling is enabled)
 *
 * \see \ref page_debug_profiling
 * \see wosh::SystemMonitor
 * \see wosh::SystemError
 * \see wosh::SystemProfiler
 *
 * Objects might easily raise a wosh::SystemError as following snippet:
 * \code
SystemError::raise(	this,
					Log,
					SystemError::CRITICAL,
					0,
					"saveAutomations",
					"FAILED#%d saving Database %s..", ret, xmlFile.getPathLocal().c_str() );
 * \endcode
 *
 * \warning SystemError::raise and logging-interleaving is going to change in WOSH 0.8.5xx
 *          in order to simplify call but provide more information and relations with
 *          the state of caller. Potentially, a custom SystemError could force the system
 *          to destroy and restore the failed component.
 *
 ****************************************************************************/
/* Copyright (c) 2007-2010, WOSH - Wide Open Smart Home 
 * by Alessandro Polo - OpenSmartHome.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the OpenSmartHome.com WOSH nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ThreadS;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ****************************************************************************/

#ifndef __WOSH_Core_SystemMonitor_H__
 #define __WOSH_Core_SystemMonitor_H__

 #include <woshDefs.h>
 #include <core/WoshModule.h>
 #include <core/SystemError.h>

#ifdef _ENABLE_PROFILING
 #include <core/SystemProfiler.h>
#endif


namespace wosh {

 #define _SystemMonitor_NAME					"SystemMonitor"
 #define _SystemMonitor_URI						":Monitor"

 #define _SystemMonitor_KEY_SaveOnExit			"SaveOnExit"
 #define _SystemMonitor_KEY_ProcessPID			"ProcessPID"
 #define _SystemMonitor_KEY_SystemUser			"SystemUser"

 #define _SystemMonitor_METHOD_inspect			"inspect"

 #define _SystemMonitor_METHOD_deprecated		"deprecated"
 #define _SystemMonitor_METHOD_profiles			"profiles"
 #define _SystemMonitor_METHOD_dsm				"dsm"

 #define _SystemMonitor_METHOD_save_errors		"save_errors"
 #define _SystemMonitor_METHOD_clear_errors		"clear_errors"

 #define _SystemMonitor_METHOD_update_sysinfo	"update_sysinfo"

 #define _SystemMonitor_SystemInfoMinRefresh	1


class WoshKernel;

class SystemMonitor : public WoshModule
 {
	WOSH_MODULE(wosh::SystemMonitor)

	typedef ListT<wosh::SystemError*> tSystemErrorList;


	protected:
		/**
		 * @brief  Default constructor. Call base constructor and initialize some properties and hosted methods.
		 * @param parent [in] WoshKernel singleton, passed to WoshModule constructor
		 * @note   Called by WoshKernel only. Static getter (gamma singleton) will return NULL until kernel is created.
		 */
		SystemMonitor( const WoshKernel* parent = NULL );

		/**
		 * @brief  Call base class implementation and (synch) update system informations.
		 * @return result of WoshModule::onKernelInitializing() + updateSystemInfo
		 * @see    updateSystemInfo()
		 */
		WRESULT onKernelInitializing();
		/**
		 * @brief  Eventually save SystemErrors list and call base class implementation.
		 * @return result of WoshModule::onKernelInitializing() + mmDoSaveErrors
		 * @see    mmDoSaveErrors()
		 */
		WRESULT onKernelStopped();

		friend class wosh::WoshKernel;

	public:
		/**
		 * @brief  Destructor. SystemError list is destroyed (nested).
		 */
		virtual ~SystemMonitor();

//@}
/** @name Public methods
 * @{
 ******************************************************************************/
	public:
		/**
		 * @brief  Update System information, the fields are OS-dependent. Reentrant.
		 * @return WRET_OK on success, a custom error code on failure while gathering information
		 * @see    updateSystemInfo_()
		 */
		WRESULT updateSystemInfo()		{ return updateSystemInfo_(true, true); }

//@}
/** @name Message Events (incoming message)
 * @{
 ******************************************************************************/
	public:
		void busMessage( const Message& message, const Bus* source );
//@}
/** @name IPropertiesProviderListener interface
 * @{
 ******************************************************************************/
 	protected:
		bool readingProperty( Property* property_curr, const PropertiesProvider* source );
		friend class wosh::PropertiesProvider;
//@}
/** @name Internal Mehods and SystemError management
 * @{
 ******************************************************************************/
	protected:
		///@todo TO BE REDESIGNED
		///@deprecated TO BE REDESIGNED
		static WRESULT raiseError( SystemError* error, const Object* source = NULL );
		friend class wosh::SystemError;	///< allow some access from my child-object

	private:
		/**
		 * @brief  Access the SystemMonitor singleton. Gamma Pattern.
		 *         Static reference is allocated and detroyed by WoshKernel on constructor/destructor respectively
		 * @return pointer to SystemMonitor singleton. May be NULL (if kernel has not been allocated yet)
		 */
		static SystemMonitor* getInstance();

		/**
		 * @brief  Update System information, the fields are OS-dependent.
		 * @param  lock_props [in] when true the method is reentrant, else it won't lock Properties list
		 * @param  force_update [in] flag used to ignore data-timeout evaluation
		 * @return WRET_ERR_ILLEGAL_USE if force_update is false and data is up-to-date;
		 *         WRET_ERR_INTERNAL on errors; WRET_OK else
		 */
		WRESULT updateSystemInfo_( bool lock_props, bool force_update );
//@}
	private:
		Response* mmDoProfilesList( const Request* request );
		WRESULT mmDoCleanErrors();
		WRESULT mmDoSaveErrors();
		Response* mmDoListDeprecated( const Request* request );

	private:
		tSystemErrorList errorLog;	///< error list
		long systemInfoTs;			///< timestamp of system-info data (epoch)

#ifdef _ENABLE_PROFILING
		SystemProfiler* profiler;	///< system-profiling manager (meyer singleton reference)
#endif


}; // class def

}; // namespace wosh

#endif //__WOSH_Core_SystemMonitor_H__
